"""
    Commandline program for working with the web server log database and storing
    the results in a sql database for customized analysis.
    
    What the program should do is read a range of different file formats
    
"""

web_log_configuration_file = "configure_web_stats.db3"

from web_stats_class import *
from configure_web_logs import *
from utility_functions import *


def build_dictionary_from_args(sys_args,supported_args={"help":None,"update":None, "list":None,"add" : None, "delete" : None, "set" : None,"write_delimited" : None,
                                                        "path" : type(""), "rotated_path": type(""),"connection_string" : type(""),"delimiter" : type(""),"id" : type(0),
                                                        "request_time" : type(0),"ip" : type(0),"url" : type(0), "response" : type(0), "size" : type(0), 
                                                        "response_time" : type(0), "domain_name" : type(0),"referer" : type(0),"user_agent" : type(0),"user_name" : type(0)}):
    """A simplistic command line argument parser. It makes no assumptions about the order the commands are given.
    You can have only one command at a time with options"""
    argument_dictionary = {}
    for arg in sys_args:
        split_arg = arg.split('=')
        if len(split_arg) == 1:
            if split_arg[0] in supported_args:
                argument_dictionary[split_arg[0]] = None   
        elif len(split_arg) == 2:
            if split_arg[0] in supported_args:
                type_of_argument = supported_args[split_arg[0]]
                if type_of_argument == type(0):
                    try:
                        argument_dictionary[split_arg[0]] = int(split_arg[1])
                    except ValueError:
                        raise
                elif type_of_argument == type(""):
                    try:
                        converted_value = str(split_arg[1])
                    except ValueError:
                        raise
                    
                    if (converted_value[0] == '"' and converted_value[-1] == '"') or (converted_value[0] == "'" and converted_value[-1] == "'"):
                        converted_value = converted_value[1:-1]
                    argument_dictionary[split_arg[0]] = converted_value
                elif type_of_argument == type(0):
                    try:
                        converted_value = int(split_arg[1])
                    except ValueError:
                        raise
        else:           
            raise Exception
    return argument_dictionary

def initialize():
    WebStatsConfigure(web_log_configuration_file)
    
def list():
    configuration = WebStatsConfigure(web_log_configuration_file)
    for conf in configuration.get_all():
        print conf

def add(argument_dictionary):
    a_d = argument_dictionary
    configuration = WebStatsConfigure(web_log_configuration_file)
    configuration.add(a_d["path"],
                      a_d["connection_string"],
                      a_d["delimiter"],
                      has_key_value(a_d,"request_time"),
                      has_key_value(a_d,"ip"),
                      has_key_value(a_d,"url"),
                      has_key_value(a_d,"response"),
                      has_key_value(a_d,"size"),
                      has_key_value(a_d,"response_time"),
                      has_key_value(a_d,"domain_name"),
                      has_key_value(a_d,"referer"),
                      has_key_value(a_d,"user_agent"),
                      has_key_value(a_d,"user_name"),
                      has_key_value(a_d,"rotated_path"))

def set(argument_dictionary):
    a_d = argument_dictionary
    if a_d.has_key("id"):
        configuration = WebStatsConfigure(web_log_configuration_file)
        
        value_dictionary = {}
        
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"path","log_file_path")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"rotated_path","log_rotated_file_path")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"connection_string","db_connection_string")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"delimiter")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"request_time","position_request_date_time")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"ip","position_client_ip")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"url","position_request_url")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"response","position_http_response_code")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"size","position_size_bytes")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"response_time","position_response_time_secs")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"domain_name","position_domain_name")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"referer","position_user_name")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"user_agent","position_user_agent")
        value_dictionary = has_key_value_set_new_dict(a_d,value_dictionary,"user_name","position_user_name")
        
        configuration.set(a_d["id"],value_dictionary)

        
def delete(argument_dictionary):
    configuration = WebStatsConfigure(web_log_configuration_file)
    configuration.delete(argument_dictionary["id"])
    
def update(argument_dictionary):
    configuration = WebStatsConfigure(web_log_configuration_file)
    
    if "id" in argument_dictionary:
        all_configurations = []
        all_configurations.append(configuration.get(argument_dictionary["id"]))
    else:
        all_configurations = configuration.get_all()
        
    for conf in all_configurations:
        print "Updating " + str(conf.id)    
        conf_hash = configuration.get_hash(conf.id)
        bw = BuildWebLogDb(conf_hash)
        bw.update()
        if conf_hash.has_key("log_rotated_file_path"): # Updated the log_rotated_uid
            hash_to_set = {}
            hash_to_set["log_rotated_uid"] = calculate_file_uid(conf_hash["log_rotated_file_path"]) 
            configuration.set(conf.id,hash_to_set)

def write_delimited(argument_dictionary):
    configuration = WebStatsConfigure(web_log_configuration_file)
    if "id" in argument_dictionary:
        conf_to_write = (configuration.get(argument_dictionary["id"]))
    else:
        print("On the command must specify id=? where ? is a number")
        sys.exit()

    conf_hash = configuration.get_hash(conf_to_write.id)
    bw = BuildWebLogDb(conf_hash)
    bw.write_delimited(bw.log_file_path + ".txt")


def help():
    return """The script "web_stats.py" builds, updates, and manages a database
of Apache server logs in a variety of formats. Currently supported database 
backends include mysql and sqlite.

Usage: 
    python web_stats.py [command] [option=value]+
    where command is:
       help --- prints this message
       initialize --- create a blank database for holding configurations
       list --- list all currently managed weblogs
       delete id=2 --- deletes the second configuration
       update --- updates all currently configured database
       write_delimited id=2
          id=1 
       add
       set
       {add or set} takes the following required value pairs
        (set also requires id=).
          path="/var/log/apache2/access.log"
          connection_string="sqlite:///var/web_stats/web_stats.db3"
          delimiter=" "
          request_time=0
          ip=3
          url=2
        and optional value pairs:
          response=6
          size=4
          response_time=5
          domain_name=9
          referer=7
          user_agent=8
          user_name=1
          rotated_path="/var/log/apache2/access.log"
        """

def has_key_value(dict,key):
    if dict.has_key(key):
        return dict[key]
    else:
        return None
    
def has_key_value_set_new_dict(old_dict,new_dict,old_key, new_key = None):
    key_value = has_key_value(old_dict,old_key)
    if not new_key:
        new_key = old_key
        
    if key_value:
        new_dict[new_key] = key_value
        
    return new_dict
    

if __name__ == "__main__":
    argument_dictionary = build_dictionary_from_args(sys.argv)

    if "help" in argument_dictionary:
        print help()     
        
    elif "initialize" in argument_dictionary:
        initialize()
        
    elif "list" in argument_dictionary:
        list()
        
    elif "add" in argument_dictionary:
        add(argument_dictionary)
        
    elif "set" in argument_dictionary:
        set(argument_dictionary)
        
    elif "update" in argument_dictionary:
        update(argument_dictionary)

    elif "write_delimited" in argument_dictionary:
        write_delimited(argument_dictionary)
        
    elif "delete" in argument_dictionary:
        delete(argument_dictionary)
        
# python web_stats.py add path="/home/janos/workspace/web_stats/test/creative.log.sample" connection_string="sqlite:////home/janos/workspace/web_stats/creative_log_sample.db3" delimiter="|" request_time=0 ip=3 url=2 response=6 size=4 response_time=5
# python web_stats.py update     
